#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct QNode* PtrToQNode;

typedef int ElementType;

typedef int Position;

struct QNode {
    ElementType* Data;
    Position Front, Rear;
    int Maxsize;
};

typedef PtrToQNode Queue;

Queue CreateQueue ( int Maxsize );

bool IsFull ( Queue Q );

bool AddQ ( Queue Q, ElementType X );

bool IsEmpty ( Queue Q );

ElementType DeleteQ ( Queue Q );

int main() {
    Queue Q = CreateQueue(10);
    int choice, X, result, i;
    while(1) {
        printf("Queue\r\nPlease input\r\n1 Add\t2 Delete\n3 Print\t4 Exit\n");
        scanf("%d",&choice);
        switch (choice) {
        case 1:
            if ( IsFull(Q) ) {
                printf("Full\n");
                exit(-9);
            }
            printf("Please input\n");
            scanf("%d",&X);
            if ( AddQ(Q,X) ) printf("Success Add\n");
            break;
        case 2:
            if ( IsEmpty(Q) ) {
                printf("Empty\n");
                exit(-9);
            }
            result = DeleteQ(Q);
            printf("Delete\t%d\n",result);
            break;
        case 3:
            printf("data\n");
            for ( i = 0; i < 10; i++ ) printf("%d\t|\t%d\n",i+1,Q->Data[i]);
            break;
        case 4:
            while(!IsEmpty(Q)) {
                DeleteQ(Q);
                printf("Delete Success\n");
            }
            printf("Free success!\n");
            exit(0);
            break;
        }
    }
    return 0;
}

Queue CreateQueue ( int Maxsize ) {
    Queue Q;
    Q = (Queue)malloc(sizeof(struct QNode));
    Q->Data = malloc( Maxsize * sizeof(ElementType) );
    Q->Front = Q->Rear = 0;
    Q->Maxsize = Maxsize;
    return Q;
}

bool IsFull ( Queue Q ) {
    return ( ( Q->Rear + 1 ) % Q->Maxsize == Q->Front );
}

bool AddQ ( Queue Q, ElementType X ) {
    if ( IsFull(Q) ) {
        printf("Full\n");
        return false;
    } else {
        Q->Rear = ( Q->Rear + 1 ) % Q->Maxsize;
        Q->Data[Q->Rear] = X;
        return true;
    }
}

bool IsEmpty ( Queue Q ) {
    return ( Q->Front == Q->Rear );
}

ElementType DeleteQ ( Queue Q ) {
    if ( IsEmpty(Q) ) {
        printf("Empty\n");
        exit(-7);
    }
    Q->Front = ( Q->Front + 1 ) % Q->Maxsize;
    return Q->Data[Q->Front];
}   